﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using LeonardoNews.Models;
using LeonardoNews.Data;
using LeonardoNews.Server.Repositories;

namespace LeonardoNews.Server.Controllers
{
    public class VotesController : ApiController
    {
        private readonly VotesRepository votesRepository;
        private readonly ArticlesRepository articlesRepository;

        public VotesController()
        {
            this.votesRepository = new VotesRepository();
            this.articlesRepository = new ArticlesRepository();
        }

        // GET api/Votes
        public IEnumerable<Vote> GetVotes()
        {
            var votes = votesRepository.GetVotes();
            return votes;
        }

        // GET api/Votes/5
        public Vote GetVote(int id)
        {
            Vote vote = votesRepository.GetVote(id);
            if (vote == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            return vote;
        }

        // PUT api/Votes/5
        public HttpResponseMessage PutVote(int id, Vote vote)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }

            if (id != vote.ID)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            try
            {
                this.votesRepository.PutVote(vote);
                this.UpdateVoteResult(vote);
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        // POST api/Votes
        public HttpResponseMessage PostVote(Vote vote)
        {
            if (ModelState.IsValid)
            {
                this.votesRepository.PostVote(vote);
                this.UpdateVoteResult(vote);
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, vote);
                response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = vote.ID }));
                return response;
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }

        // DELETE api/Votes/5
        public HttpResponseMessage DeleteVote(int id)
        {
            Vote vote;
            try
            {
                vote = votesRepository.DeleteVote(id);
            }
            catch (NullReferenceException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK, vote);
        }

        private void UpdateVoteResult(Vote vote)
        {
            var article = this.articlesRepository.GetSingle(vote.Article.ID);

            if (vote.State == 1)
            {
                article.VoteResult++;
            }
            else if (vote.State == -1)
            {
                article.VoteResult--;
            }
            else
            {
                return;
            }

            this.articlesRepository.Update(article.ID, article);
        }
    }
}